package org.rainbowinverted.charging.device.connect.ykc.server.handler;

import org.rainbowinverted.charging.device.connect.ykc.server.constants.YkcDeviceStartChargeErrorReason;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcDeviceStartChargeIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.in.YkcMessageIn;
import org.rainbowinverted.charging.device.connect.ykc.server.message.out.YkcDeviceStartChargeOut;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandler;
import io.netty.channel.ChannelHandlerContext;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

/**
 * 开始充电
 * @author hehuaiping
 */
@Slf4j
@Component
@ChannelHandler.Sharable
public class YkcDeviceStartChargeHandler extends YkcAbstractHandler<YkcDeviceStartChargeIn,
        YkcDeviceStartChargeOut> {
    @Override
    public void read(ChannelHandlerContext channel, YkcMessageIn message) {
        ByteBuf messageBody = message.getMessageBody();
        // 订单编号
        String orderNo = readOrderNo(messageBody);
        // 设备编号
        Long deviceNo = readDeviceNo(messageBody);
        // 枪号
        Integer gunNo = readGunNo(messageBody);
        // 控制结果
        Boolean controlResult = messageBody.readByte() == 0x01;
        // 失败原因
        String errorReason = parseErrorReason(messageBody.readByte());
        YkcDeviceStartChargeIn ykcDeviceStartChargeIn = YkcDeviceStartChargeIn.of(
                orderNo, deviceNo, gunNo, controlResult, errorReason);
        complete(message.getFrameSerialNo(), ykcDeviceStartChargeIn);
        log.info("device start charge control info: {}", ykcDeviceStartChargeIn);
    }

    @Override
    public void write(ByteBuf byteBuf, YkcDeviceStartChargeOut ykcDeviceStartChargeOut) {
        // 订单编号
        writeOrderNo(byteBuf, ykcDeviceStartChargeOut.getOrderNo());
        // 设备编号
        writeDeviceNo(byteBuf, ykcDeviceStartChargeOut.getDeviceNo());
        // 枪号
        writeGunNo(byteBuf, ykcDeviceStartChargeOut.getGunNo());
        // 逻辑卡号
        byteBuf.writeLong(ykcDeviceStartChargeOut.getCardNo());
        // 物理卡号
        byteBuf.writeLongLE(ykcDeviceStartChargeOut.getCardNo());
        // 账户余额
        byteBuf.writeIntLE(ykcDeviceStartChargeOut.getBalance());
        createCompletableFuture(ykcDeviceStartChargeOut.getFrameSerialNo());
    }

    private String parseErrorReason(Byte errorReasonByte) {
        switch (errorReasonByte) {
            case 0x00:
                return YkcDeviceStartChargeErrorReason.NONE;
            case 0x01:
                return YkcDeviceStartChargeErrorReason.DEVICE_NO_NOT_MATCH;
            case 0x02:
                return YkcDeviceStartChargeErrorReason.ALREADY_CHARGING;
            case 0x03:
                return YkcDeviceStartChargeErrorReason.DEVICE_FAILURE;
            case 0x04:
                return YkcDeviceStartChargeErrorReason.GUN_DEVICE_OFF_LINE;
            case 0x05:
                return YkcDeviceStartChargeErrorReason.NOT_INSERTED;
            default:
                return YkcDeviceStartChargeErrorReason.UNKNOWN;
        }
    }
}
